package com.javacoo.swing.jxbrowser.engine;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigInteger;
import java.nio.channels.FileLock;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableModel;

import com.javacoo.swing.jxbrowser.BaseBrowser;
import com.javacoo.xkernel.spi.ExtensionLoader;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.BrowserContext;
import com.teamdev.jxbrowser.chromium.BrowserContextParams;
import com.teamdev.jxbrowser.chromium.BrowserPreferences;
import com.teamdev.jxbrowser.chromium.StorageType;
import com.teamdev.jxbrowser.chromium.ba;
import com.teamdev.jxbrowser.chromium.events.DisposeEvent;
import com.teamdev.jxbrowser.chromium.events.DisposeListener;
import com.teamdev.jxbrowser.chromium.events.RenderAdapter;
import com.teamdev.jxbrowser.chromium.events.RenderEvent;
import com.teamdev.jxbrowser.chromium.swing.BrowserView;

import lombok.extern.slf4j.Slf4j;
import static javax.swing.ListSelectionModel.SINGLE_SELECTION;

/**
 * 创建浏览器
 * <p>
 * 说明:
 * </p>
 * 必须使用BrowserContext初始化每个Browser实例。该BrowserContext实例包含需要一个浏览会话的上下文，并提供对目录路径铬店的cookies，缓存中的数据文件等。
 *
 * 以下代码创建使用默认上下文初始化的新Browser实例：
 *
 * Browser browser = new Browser();
 *
 * 上面的代码等于：
 *
 * Browser browser = new Browser(BrowserContext.defaultContext());
 *
 * 该BrowserContext.defaultContext（）方法返回默认BrowserContext被配置为存储的Chromium数据文件，如cookies，高速缓存等，在Mac OS和Linux用户的临时目录，在Windows上 的目录是：AppData\Local\JxBrowser 。您可以使用BrowserPreferences.getDefaultDataDir（）方法获取存储数据文件的目录的路径。
 *
 * 具有相同BrowserContext实例的两个Browser实例将使用相同的用户数据目录。因此，他们将共享cookie和缓存文件。例如：
 *
 * BrowserContext context = new BrowserContext(
 *     new BrowserContextParams("C:\\my-data1"));
 * Browser browser1 = new Browser(context);
 * Browser browser2 = new Browser(context);
 *
 * 要创建不共享cookie和缓存数据的独立Browser实例，必须使用配置为使用不同数据目录的其他BrowserContext实例初始化每个Browser实例。例如：
 *
 * BrowserContext context1 = new BrowserContext(
 *     new BrowserContextParams("C:\\my-data1"));
 * Browser browser1 = new Browser(context1);
 *
 * BrowserContext context2 = new BrowserContext(
 *     new BrowserContextParams("C:\\my-data2"));
 * Browser browser2 = new Browser(context2);
 *
 * 要获取Browser实例的BrowserContext，您可以使用browser.getContext（）方法。
 * 重要事项
 *
 * 禁止在单个或多个Java应用程序实例中使用配置为使用相同数据目录的多个BrowserContext实例。在这种情况下，浏览器构造函数将抛出BrowserException异常，以防止出现意外行为或错误，例如Chromium引擎中的本机崩溃。
 *
 * 如果可以在同一台计算机上同时启动多个Java应用程序实例，那么请不要使用默认构造函数在应用程序中创建Browser实例。在这种情况下，同时在不同Java应用程序中运行的两个Browser实例将被配置为使用被禁止的相同Chromium数据目录。当第二的Java应用程序实例将尝试创建一个新的浏览器实例，该BrowserException会抛出异常，
 *
 * 要解决此问题，请确保只能同时使用Java应用程序的一个实例。如果您希望让最终用户同时运行Java应用程序的多个实例，请确保Java应用程序的每个实例都配置JxBrowser库以使用唯一的Chromium数据目录。
 *
 *
 * 多个BrowserContext限制
 * 目前，一个Chromium进程可以容纳多少个BrowserContext实例的限制。保持超过该限制可能会导致Chromium进程出现意外崩溃。限制是每个进程大约50个BrowserContext实例，并根据操作系统而有所不同。
 * 在Linux和MacOS上，Chromium不会发布其文件描述符。这种行为导致文件描述符泄漏，并且在某些时候，由于达到了文件描述符的硬限制，因此无法创建新的BrowserContext实例。
 *
 * 在Windows上，新的BrowserContext实例从Chromium线程本地存储池中获取线程本地存储，并且永远不会释放它们，这可能会在尝试创建新的BrowserContext时导致Chromium进程崩溃。
 *
 * 为避免多个BrowserContext实例出现问题，可以使用以下方法：
 * 1.多个浏览器实例可以使用相同的BrowserContext。如果您不需要创建不共享cookie，缓存和其他用户数据的浏览器实例，则可以使用单个BrowserContext实例。例如：
 *
 * BrowserContext browserContext = new BrowserContext(new BrowserContextParams(
 *         new File("user_data_dir").getAbsolutePath()));
 * Browser browserOne = new Browser(browserContext);
 * Browser browserTwo = new Browser(browserContext);
 *
 * 2.如果您需要使用不共享cookie和其他用户数据的多个Browser实例，并且您必须创建多个BrowserContext实例，我们建议您定期dispose所有Browser实例以销毁所有已创建的BrowserContext实例，并终止Chromium native发布文件描述符和其他资源的过程。之后，您可以继续创建新的BrowserContext和Browser实例。
 *
 * @author DuanYong
 * @since 2018年10月16日上午10:02:01
 */
@Slf4j
public class CreatingBrowser extends BaseBrowser {


	/**
	 * 系统入口
	 * <p>说明:</p>
	 * <li></li>
	 * @author duanyong@jccfc.com
	 * @date 2020/6/7 14:47
	 */
	public static void main(String[] args) {
        BrowserContext context = new BrowserContext(
            new BrowserContextParams("C:\\my-data1"));

        Browser browser1 = new Browser(context);
        Browser browser2 = new Browser(context);
        //
        //多个BrowserContext限制
        BrowserContext browserContext = new BrowserContext(new BrowserContextParams(
            new File("user_data_dir").getAbsolutePath()));
        Browser browserOne = new Browser(browserContext);
        Browser browserTwo = new Browser(browserContext);
	}
}
